package com.msh.automatic.android.control.service

import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.os.PowerManager
import android.provider.Settings
import android.util.Log
import androidx.core.app.NotificationCompat
import com.alibaba.fastjson2.JSON
import com.alibaba.fastjson2.JSONObject
import com.msh.automatic.android.control.R
import com.msh.automatic.android.control.task.AppTask
import com.msh.automatic.android.control.task.Task
import com.msh.automatic.android.control.task.TaskLog
import com.msh.automatic.android.control.task.TaskManager
import com.msh.automatic.android.control.util.AccessibilityServiceUtil
import com.msh.automatic.android.control.util.ConfigUtil
import com.msh.automatic.android.control.util.EventUtil
import com.msh.automatic.android.control.util.EventUtil.Message
import com.msh.automatic.android.control.util.MqttMessageType
import com.msh.automatic.android.control.util.api.DeviceApi
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.eclipse.paho.client.mqttv3.*
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence

class MqttService : Service() {
    var mqttClient: MqttClient? = null
    private var wakeLock: PowerManager.WakeLock? = null


    companion object {
        const val CHANNEL_ID = "foreground_service_channel"
        const val NOTIFICATION_ID = 1
        private const val TAG = "MqttService"
        private const val SERVER_URI = "wss://emqx-mqtt.jobeyond.cn/mqtt" // 公共测试服务器
        lateinit var mqttService:MqttService
    }

    override fun onCreate() {
        super.onCreate()
        mqttService = this
        Log.d(TAG, "onCreate")
        createNotificationChannel()
        connectionMqtt()
        if (wakeLock == null) {
            val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
            wakeLock = powerManager.newWakeLock(
                PowerManager.SCREEN_DIM_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP,
                "MyAccessibilityService:WakeLock"
            )
            wakeLock?.acquire()
        }
        GlobalScope.launch {
            while (true){
                val (code,message,body) = DeviceApi.heartbeat(TaskManager.getTaskLogId(),this@MqttService)
                body?.let {
                    if(it.getString("status").equals("over")){
                        TaskManager.currentBaseTask = null
                        AccessibilityServiceUtil.goHome(AIAccessibilityService.aiAccessibilityService)
                    }
                }
                delay(60_000)  // 30秒
            }
        }
        TaskManager.start()
    }
    @SuppressLint("ForegroundServiceType")
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d(TAG, "Service started")
        val notification = buildNotification()
        startForeground(NOTIFICATION_ID, notification)
        connectionMqtt()
        // 做实际的工作，比如启动子线程
        return START_REDELIVER_INTENT
    }
    private fun connectionMqtt(){
        if(mqttClient != null ){
            var mqttClient = this.mqttClient!!
            if(mqttClient.isConnected){
                return
            }
            mqttClient.disconnect()
            mqttClient.close()
        }
        val jwt = ConfigUtil.getJwt(this)!!
        val clientId = Settings.Secure.getString(this.contentResolver, Settings.Secure.ANDROID_ID)
        val token = ConfigUtil.getToken(this)!!

        val persistence = MemoryPersistence()
        var mqttClient = MqttClient(SERVER_URI, clientId,persistence)

        val options = MqttConnectOptions().apply {
            isCleanSession = true
            connectionTimeout = 10
            keepAliveInterval = 20
            userName = jwt.subject
            password = token.toCharArray()
            isAutomaticReconnect=true
        }

        try {
            mqttClient.setCallback(object : MqttCallbackExtended {
                override fun messageArrived(topic: String?, message: MqttMessage?) {
                    Log.d(TAG, "Message received: ${message.toString()} on topic: $topic")
                }

                override fun connectionLost(cause: Throwable?) {
                    Log.e(TAG, "Connection lost: ${cause?.message}")
                }

                override fun deliveryComplete(token: IMqttDeliveryToken?) {
                    Log.d(TAG, "Message delivered")
                }

                override fun connectComplete(reconnect: Boolean, serverURI: String?) {
                    Log.d(TAG, "connectComplete ${reconnect}")
                    mqttClient.subscribeWithResponse("user/"+jwt.subject,2
                    ) { topic, message ->
                        val mqttPayload = message.payload?.toString(Charsets.UTF_8) ?: ""
                        val data = JSON.parseObject(mqttPayload)
                        val mqttId = message.id
                        val mqttTopic = topic
                        val mqttQos = message.qos
                        val msg = Message.MqttMessage(
                            mqttId,
                            mqttTopic,
                            mqttQos,
                            mqttPayload,
                            data.getJSONObject("task").toJavaObject(Task::class.java),
                            data.getJSONObject("taskLog").toJavaObject(TaskLog::class.java)
                        )
                        val res = EventUtil.EventBus.tryPost(msg)
                        Log.d(TAG, "messageArrived ${res} ${topic} ${mqttPayload}")
                        TaskManager.startTask(AppTask(msg.task,msg.taskLog))
                    }
                }
            })
            val token = mqttClient.connectWithResult(options)
        } catch (e: MqttException) {
            Log.e(TAG, "MQTT exception: ${e.message}")
        }
        this.mqttClient = mqttClient
    }
    private fun buildNotification(): Notification {
        val notificationIntent = Intent(this, MqttService::class.java)
        val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)

        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle(getString(R.string.app_name))
            .setContentText(getString(R.string.app_desc))
            .setSmallIcon(R.mipmap.ic_launcher) // 换成你项目里的图标
            .setContentIntent(pendingIntent)
            .setOngoing(true) // 用户不能滑动取消
            .build()
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                getString(R.string.app_desc),
                NotificationManager.IMPORTANCE_LOW
            )
            val manager = getSystemService(NotificationManager::class.java)
            manager.createNotificationChannel(channel)
        }
    }
    override fun onBind(intent: Intent?): IBinder? {
        return null // 如果你想支持绑定服务，可自定义返回 Binder
    }

    override fun onDestroy() {
        super.onDestroy()
        if (wakeLock?.isHeld == true) {
            wakeLock?.release()
            wakeLock = null
        }
        try {
            if(mqttClient != null){
                var mqttClient = this.mqttClient!!
                mqttClient.disconnect()
                mqttClient.close()
            }

        } catch (e: MqttException) {
            Log.e(TAG, "Disconnect error: ${e.message}")
        }

        TaskManager.stop()
    }
}
